package project;

import oracle.kv.KVStore;
import oracle.kv.KVStoreConfig;
import oracle.kv.KVStoreFactory;

public class Etape_1_a {
	// nombre de application
	public static int C = 10;
	// matrix de store
	public static KVStore[] stores;

	// Initialisation du Kvstore dans la cote d'application
	public static void init() {
		// noms de kvstore - ici on manipule dans un kvstore
		String[] storeNames = new String[Init_1_a.N];
		storeNames[0] = "kvstore";
		storeNames[1] = "kvstore";
		// adresse de kvstore - ici on manipule dans un kvstore
		String[] hostNames = new String[Init_1_a.N];
		hostNames[0] = "localhost";
		hostNames[1] = "localhost";
		// numero du port de kvstore - ici on manipule dans un kvstore
		String[] hostPorts = new String[Init_1_a.N];
		hostPorts[0] = "5000";
		hostPorts[1] = "5000";

		stores = new KVStore[Init_1_a.N];
		for (int i = 0; i < Init_1_a.N; i++) {
			stores[i] = KVStoreFactory.getStore(new KVStoreConfig(
					storeNames[i], hostNames[i] + ":" + hostPorts[i]));
		}
	}

	/**
	 * la fonction principe de Etape 1 a.
	 * 
	 * creer C applications, chaque application execute 1000 transactions.
	 * */
	public static void main(String[] args) {
		init();
		Application[] applications = new Application[C];
		for (int i = 1; i <= C; i++) {
			// creer un nouveau thread
			applications[i - 1] = new Application(stores, i);
		}
		// lancer les C threads
		for (int i = 1; i <= C; i++) {
			applications[i - 1].start();
		}

		System.out.println("Average Time: " + getAverageTime(applications)
				+ "ms");
	}

	/**
	 * Obtenir le temps moyenne d'execution pour C applications
	 * 
	 * @param applications
	 *            la vecteur d'application
	 * @return le temps moyenne d'execution
	 * */
	public static long getAverageTime(Application[] applications) {
		// verifier que les threads sont fini ou pas.
		boolean isFinished = true;
		do {
			isFinished = true;
			// iterer dans C applications
			for (int i = 1; i <= C; i++) {
				// Si il y a de thread qui est pas fini
				if (applications[i - 1].getState() != Thread.State.TERMINATED) {
					isFinished = false;
					break;
				}
			}
		} while (!isFinished);

		long waitTimeTotal = 0;
		// calculer le temps total
		for (int i = 1; i <= C; i++) {
			// ajouter le temps d'execution de application i-1
			waitTimeTotal += applications[i - 1].getWaitTime();
		}
		// calculer le temps moyenne
		return waitTimeTotal / C;
	}
}
